﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace AfterCaveStory
{
    class PhysicsObject : AnimatedObjetc
    {
        public Vector2 velocity;
        public Boolean isStatic;
        public Boolean onGround;
        public double movementAngle;
        private float friction;
        public float aceleration;
        
        
        public PhysicsObject(Texture2D textura, Nullable<Rectangle> sourceRectangle, float depth)
            : base(textura, sourceRectangle, depth)
        {
            velocity = Vector2.Zero;
            isStatic = true;
            onGround = false;
            movementAngle = 90;
            friction = 0.04f;
            aceleration = 0.2f;
        }

        public virtual void update(World world)
        {
            if (!isStatic)
            {
                verifyGravity(world);
                verifyOnGround();
                verifyFriction();
                verifyMoviment(world);
                verifyCollisions(world);
                verifyMovementAnge();
            }
        }

        private void verifyGravity(World world)
        {
            this.velocity.Y += world.gravidade;
        }

        private void verifyFriction()
        {
            if (onGround)
            {
                if ((velocity.X > -aceleration) && (velocity.X < aceleration))
                {
                    velocity.X = 0;
                }

                if (velocity.X > 0)
                {
                    velocity.X -= friction;
                }
                else if (velocity.X < 0)
                {
                    velocity.X += friction;
                }

            }
        }

        private void verifyMoviment(World world)
        {
            this.x += velocity.X;
            this.y += velocity.Y;
        }

        private void verifyCollisions(World world)
        {
            for (int i = 0; i < world.objectList.Count; i++)
            {
                if (world.objectList[i] is Platform)
                {
                    if (this.collisionBounds.Intersects(world.objectList[i].collisionBounds))
                    {

                        //this.velocity.Y = world.gravidade;
                        //this.y = world.objectList[i].y - world.objectList[i].Height / 2 - this.Height / 2;
                        //onGround = true;
                        //friction = 0.08f;
                        handlePlatformCollision(world, world.objectList[i]);
                    }
                }
            }
        }

        private void verifyOnGround()
        {
            if ((velocity.Y > 1) || (velocity.Y < -1))
            {
                onGround = false;
            }
        }

        private void verifyMovementAnge()
        {
            movementAngle = Math.Atan2(velocity.Y, velocity.X) * 180 / Math.PI;
        }

        private void handlePlatformCollision(World world, PhysicsObject platform)
        {
            var angleRadian = Math.Atan2(this.y - platform.y, this.x - platform.x);
            var angleDegree = angleRadian * 180 / Math.PI;

            if (angleDegree < 0)
            {
                angleDegree = (-angleDegree * -1) + 360;
            }



            //Console.WriteLine(angleDegree);
            //colisão por cima

            if (angleDegree >= 225 && angleDegree <= 316 && movementAngle > 0 && movementAngle <= 180)
            {
                velocity.Y = world.gravidade;
                this.y = ((platform.y - platform.Height / 2) - this.Height / 2);
                friction = 0.08f;
                onGround = true;
            }
            //colisão pela direita
            else if (angleDegree >= 135 && angleDegree < 225)
            {
                velocity.X = 0;
                this.x = ((platform.x - platform.Width / 2) - this.Width / 2) - 0.5f;
                Console.WriteLine(angleDegree);
            }
            //colisão pela esquerda
            else if ((angleDegree > 316 && angleDegree <= 360) || (angleDegree >= 0 && angleDegree <= 45))
            {
                velocity.X = 0;
                this.x = ((platform.x + platform.Width / 2) + this.Width / 2) + 1;
                Console.WriteLine(angleDegree);
            }
            //colisão prr baixo
            else if (angleDegree > 45 && angleDegree < 135)
            {
                velocity.Y = 0;
                this.y = ((platform.y + platform.Height / 2) + this.Height / 2) + 2;
            }
        }
    }
}
